package com.example.lab04.dao.Impl;

import com.example.lab04.dao.GenericDao;
import com.example.lab04.entity.User;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.thymeleaf.util.StringUtils;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

public class GenericDaoImpl<T extends Serializable,ID extends Number> implements GenericDao<T,ID> {
   @Autowired
    private SqlSession sqlSession;



    private String namespace;

    @SuppressWarnings("unchecked")
    public GenericDaoImpl() {
        //通过反射获取class对象即对象的属性和方法
        //获取对象，getGenericSuperclass()的意思是获取泛型的父类
        //getClass().getGenericSuperclass()返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type，然后将其转ParameterizedType。
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
        //getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
        //[0]就是这个数组中第一个了，简而言之就是获得超类的泛型参数的实际类型。
        //本例中即为获得T的type。
        Class<T> clazz = (Class<T>) parameterizedType.getActualTypeArguments()[0];
        namespace = StringUtils.unCapitalize(clazz.getSimpleName());
        //StringUtils.unCapitalize方法就是将首字母变成小写将实体类User改成user
    }
    public String getStatement(String sqlId){
        return namespace.concat(".").concat(sqlId);
    }


    @Override
    public List<T> queryAll() {
        return sqlSession.selectList(getStatement("queryAll"));
    }

    @Override
    public T queryById(ID id) {
        return sqlSession.selectOne(getStatement("queryById"),id);
    }

    @Override
    public void create(T t) {
        sqlSession.insert(getStatement("create"),t);
    }

    @Override
    public void modify(T t) {
        sqlSession.update(getStatement("modify"),t);
    }

    @Override
    public void removeById(ID id) {
        sqlSession.delete(getStatement("removeById"),id);
    }

    @Override
    public T queryOne(String sqlId, Object parameter) {
        return sqlSession.selectOne(getStatement(sqlId), parameter);
    }
}
